package com.maybach.workflow.core.expression;

import com.maybach.util.MapUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.Velocity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.StringReader;
import java.io.StringWriter;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by houenxun on 15/9/28.
 */
public class VelocityExpression implements IExpression {
    Logger logger = LoggerFactory.getLogger(this.getClass());


    private Map<String, Object> commonArgs;

    public VelocityExpression() {
        commonArgs = new HashMap<String, Object>();
        /*commonArgs = new HashMap<String, Object>();
        commonArgs.put("calendarUtil", new com.dawanju.common.util.CalendarUtil());
        commonArgs.put("dateTool", new org.apache.velocity.tools.generic.DateTool());
        commonArgs.put("mhcStringUtil", new com.dawanju.common.util.MhcStringUtil());
        commonArgs.put("stringEscapeUtil", new com.alibaba.citrus.util.StringEscapeUtil());
        commonArgs.put("roleUtils", new com.dawanju.common.util.RoleUtils());
        commonArgs.put("collectionUtil", new com.dawanju.common.util.CollectionUtil());
        commonArgs.put("audiUtil", new com.dawanju.common.util.AudiUtil());
        //commonArgs.put("userTools", new com.dawanju.web.common.UserTools());

        commonArgs.put("price", new com.dawanju.common.util.PriceUtil());
        commonArgs.put("orderStatusUtil", new com.dawanju.common.util.OrderStatusUtil());
        commonArgs.put("date", new com.dawanju.common.util.DateUtil());
        commonArgs.put("flow", new com.dawanju.common.flow.FlowHelper());
        commonArgs.put("errorCode", new com.dawanju.common.util.ErrorCode());
        commonArgs.put("encrypt", new com.dawanju.common.util.EncryptUtil());
        commonArgs.put("asset", new com.dawanju.common.util.AssetKeyUtil());
        commonArgs.put("transferPV", new com.dawanju.common.util.TransferPVUtil());


        commonArgs.put("workFlow", new com.dawanju.flow.helper.WorkFlowHelper());
        commonArgs.put("enum", new com.dawanju.common.util.EnumUtil());
        commonArgs.put("newFlow", new com.dawanju.flow.NewFlowHelper());*/
    }


    @Override
    public <T> T eval(Class<T> T, String expr, Map<String, Object> args) {
        VelocityContext context = new VelocityContext();
        String result = null;
        if (StringUtils.isBlank(expr)) {
            result = expr;
        } else {
            if (null != args) {
                for (String key : args.keySet()) {
                    context.put(key, args.get(key));
                }
            }
            for (String key : commonArgs.keySet()) {
                context.put(key, commonArgs.get(key));
            }


            StringWriter writer = new StringWriter();
            if (!Velocity.evaluate(context, writer, "VelocityExpression", new StringReader(expr))) {
                logger.error("解析表达式错误 expr={}, args={}", expr, args);
                return null;
            }
            result = writer.getBuffer().toString();
        }

        if (T.equals(String.class)) {
            return (T) result;
        } else if (T.equals(Boolean.class)) {
            return (T) new Boolean(Boolean.parseBoolean(result));
        } else if (T.equals(Integer.class)) {
            return (T) MapUtil.INTEGER_PARSER.parse(result);
        } else if (T.equals(Long.class)) {
            return (T) MapUtil.LONG_PARSER.parse(result);
        } else if (T.equals(Float.class)) {
            return (T) new Float(Float.parseFloat(result));
        }
        return (T) result;
    }

    public Map<String, Object> getCommonArgs() {
        return commonArgs;
    }

    public void setCommonArgs(Map<String, Object> commonArgs) {
        this.commonArgs = commonArgs;
    }
}
